// dtctest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include "portable.h"
#include "hc256.h"

static void fhexprint( FILE *fp, unsigned char *data, unsigned int length );

int _tmain(int argc, _TCHAR* argv[])
{
	FILE *fp;
	int rv = 0;
	DTErr err = DT_E_NOERR;
	hc256 *cipher = NULL;

    static unsigned char key[] = {
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	};

	static unsigned char iv[] = {
		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	};

	static unsigned char expected[] = {
		0xbf, 0xa2, 0xe2, 0xaf, 0xe9, 0xce, 0x17, 0x4f,
		0x8b, 0x05, 0xc2, 0xfe, 0xb1, 0x8b, 0xb1, 0xd1,
		0xee, 0x42, 0xc0, 0x5f, 0x01, 0x31, 0x2b, 0x71,
		0xc6, 0x1f, 0x50, 0xdd, 0x50, 0x2a, 0x08, 0x0b,
		0xed, 0xfe, 0xc7, 0x06, 0x63, 0x3d, 0x92, 0x41,
		0xa6, 0xda, 0xc4, 0x48, 0xaf, 0x85, 0x61, 0xff,
		0x5e, 0x04, 0x13, 0x5a, 0x94, 0x48, 0xc4, 0x34,
		0x2d, 0xe7, 0xe9, 0xf3, 0x37, 0x52, 0x0b, 0xdf
	};

	unsigned char output[64];

	unsigned int bytes_written = 0xDEADBEEF;

	do {
		if( NULL == ( fp = fopen("/dtctest.txt","w") ) ) {
			rv = 128;
			break;
		}

		fprintf( fp, "%%DTCT-I-KEY; key is\n" );
		fhexprint( fp, key, 32 );

		fprintf( fp, "%%DTCT-I-IV; iv is\n" );
		fhexprint( fp, iv, 32 );

		fprintf( fp, "%%DTCT-I-EXPECTED; expected output is\n" );
		fhexprint( fp, expected, 64 );

		if( DT_E_NOERR != ( err = hc256_new( &cipher ) ) ) {
			fprintf( fp, "%%DTCT-F-NEW; failed calling hc256_new(), error = %d.\n", err );
			rv = err;
			break;
		}
		fprintf( fp, "%%DTCT-S-NEW; called hc256_new() with no errors.\n");

		if( DT_E_NOERR != ( err = hc256_key( cipher, (char *) key ) ) ) {
			fprintf( fp, "%%DTCT-F-KEY; failed calling hc256_key(), error = %d.\n", err );
			rv = err;
			break;
		}
		fprintf( fp, "%%DTCT-S-KEY; called hc256_key() with no errors.\n");

		if( DT_E_NOERR != ( err = hc256_iv( cipher, (char *) iv ) ) ) {
			fprintf( fp, "%%DTCT-F-IV; failed calling hc256_iv(), error = %d.\n", err );
			rv = err;
			break;
		}
		fprintf( fp, "%%DTCT-S-IV; called hc256_iv() with no errors.\n");

		if( DT_E_NOERR != ( err = hc256_init( cipher ) ) ) {
			fprintf( fp, "%%DTCT-F-INIT; failed calling hc256_init(), error = %d.\n", err );
			rv = err;
			break;
		}
		fprintf( fp, "%%DTCT-S-INIT; called hc256_init() with no errors.\n");

		if( DT_E_NOERR != ( err = hc256_keystream( cipher, (char *) output, 64, &bytes_written ) ) ) {
			fprintf( fp, "%%DTCT-F-KEYSTREAM; failed calling hc256_keystream(), error = %d.\n", err );
			rv = err;
			break;
		}
		fprintf( fp, "%%DTCT-S-KEYSTREAM; called hc256_keystream() with no errors.\n");

		fprintf( fp, "%%DTCT-I-BYTES; hc256_keystream() wrote %d bytes to the output buffer.\n", bytes_written );
		if( 64 == bytes_written ) {
			fprintf( fp, "%%DTCT-S-BYTES; which is how much we were expecting.\n" );
		} else {
			fprintf( fp, "%%DTCT-E-BYTES; which is not what we expected, 64 bytes was the correct answer, thank you for playing.\n" );
		}

		fprintf( fp, "%%DTCT-I-ACTUAL; actual output is\n" );
		fhexprint( fp, output, 64 );

		if( 0 == memcmp( expected, output, 64 ) ) {
			fprintf( fp, "%%DTCT-S-ACTUAL; the expected value is the same as the actual value. w00t!\n" );
		} else {
			fprintf( fp, "%%DTCT-E-ACTUAL; the expected value differs from the actual value.\n" );
		}

		if( DT_E_NOERR != ( err = hc256_delete( cipher ) ) ) {
			fprintf( fp, "%%DTCT-F-DELETE; failed calling hc256_keystream(), error = %d.\n", err );
			rv = err;
			break;
		}
	} while( 0 );

	if( NULL != fp ) {
		fclose( fp );
	}

	return( rv );
}

static void fhexprint( FILE *fp, unsigned char *data, unsigned int length ) {
	unsigned int i;

	for( i = 0; i < length; i++ ) {
		if( 0 == ( i % 16 ) ) {
			fprintf(fp, "; " );
		}

		fprintf( fp, "%02X", ( (unsigned int) data[i] ) & 0xFF );

		if( 15 == ( i % 16 ) ) {
			fprintf( fp, "\n" );
		} else {
			fprintf( fp, " " );
		}
	}

	if( 0 != ( i % 16 ) ) {
		fprintf( fp, "\n" );
	}
}